import pandas as pd
import numpy as np

def demonstrate_melt_function():
    """
    演示Pandas中melt函数的各种用法
    """
    print("=" * 60)
    print("Pandas melt() 函数完整指南 - 宽格式转长格式")
    print("=" * 60)
    
    # 1. 基础示例：产品销售数据
    print("1. 基础示例：不同店铺的产品价格数据")
    print("-" * 40)
    
    # 创建宽格式数据
    wide_df = pd.DataFrame({
        'product_id': [101, 102, 103],
        'product_name': ['iPhone', 'iPad', 'MacBook'],
        'store_A_price': [6999, 3999, 12999],
        'store_B_price': [6899, 3899, 12799],
        'store_C_price': [7099, 4099, 13199]
    })
    
    print("原始宽格式数据:")
    print(wide_df)
    print()
    
    # 基础melt操作
    melted_basic = pd.melt(wide_df, 
                          id_vars=['product_id', 'product_name'],
                          var_name='store', 
                          value_name='price')
    
    print("基础melt转换结果:")
    print(melted_basic)
    print()
    
    # 2. 指定要转换的列
    print("2. 指定value_vars参数（只转换特定列）")
    print("-" * 40)
    
    melted_selected = pd.melt(wide_df,
                             id_vars=['product_id', 'product_name'],
                             value_vars=['store_A_price', 'store_B_price'],
                             var_name='selected_store',
                             value_name='price_value')
    
    print("只转换store_A和store_B的结果:")
    print(melted_selected)
    print()
    
    # 3. 学生成绩数据示例
    print("3. 学生各科成绩数据转换")
    print("-" * 40)
    
    grades_df = pd.DataFrame({
        'student_id': [1, 2, 3],
        'name': ['张三', '李四', '王五'],
        'math_score': [85, 92, 78],
        'english_score': [88, 79, 95],
        'science_score': [90, 85, 82],
        'history_score': [76, 88, 81]
    })
    
    print("学生成绩宽格式数据:")
    print(grades_df)
    print()
    
    # 转换所有成绩列
    grades_melted = pd.melt(grades_df,
                           id_vars=['student_id', 'name'],
                           value_vars=['math_score', 'english_score', 
                                     'science_score', 'history_score'],
                           var_name='subject',
                           value_name='score')
    
    print("成绩数据长格式转换:")
    print(grades_melted)
    print()
    
    # 4. 处理包含缺失值的数据
    print("4. 处理包含缺失值的数据")
    print("-" * 40)
    
    sales_df = pd.DataFrame({
        'month': ['Jan', 'Feb', 'Mar'],
        'region_east': [100, 150, None],
        'region_west': [120, None, 180],
        'region_north': [90, 110, 130]
    })
    
    print("包含缺失值的销售数据:")
    print(sales_df)
    print()
    
    sales_melted = pd.melt(sales_df,
                          id_vars=['month'],
                          var_name='region',
                          value_name='sales')
    
    print("转换后包含缺失值的结果:")
    print(sales_melted)
    print("\n缺失值统计:")
    print(f"缺失值数量: {sales_melted['sales'].isnull().sum()}")
    print()
    
    # 5. 多层列索引的处理
    print("5. 多层列索引的melt操作")
    print("-" * 40)
    
    # 创建多层列索引的DataFrame
    arrays = [['Q1', 'Q1', 'Q2', 'Q2'], 
              ['revenue', 'profit', 'revenue', 'profit']]
    tuples = list(zip(*arrays))
    index = pd.MultiIndex.from_tuples(tuples, names=['quarter', 'metric'])
    
    multi_df = pd.DataFrame({
        'company': ['Company_A', 'Company_B'],
        ('Q1', 'revenue'): [1000, 1500],
        ('Q1', 'profit'): [200, 300],
        ('Q2', 'revenue'): [1100, 1600],
        ('Q2', 'profit'): [250, 350]
    })
    
    print("多层列索引数据:")
    print(multi_df)
    print()
    
    # 使用col_level参数处理多层索引
    multi_melted = pd.melt(multi_df,
                          id_vars=['company'],
                          var_name='quarter_metric',
                          value_name='amount',
                          col_level=0)  # 指定使用第一层索引
    
    print("多层索引melt结果:")
    print(multi_melted)
    print()
    
    # 6. 实际应用：数据透视准备
    print("6. 实际应用：为数据透视分析准备数据")
    print("-" * 40)
    
    # 创建包含多个度量指标的数据
    business_data = pd.DataFrame({
        'year': [2020, 2021, 2022],
        'revenue_online': [500, 700, 900],
        'revenue_offline': [300, 400, 500],
        'customers_new': [1000, 1200, 1500],
        'customers_returning': [500, 600, 800]
    })
    
    print("业务数据宽格式:")
    print(business_data)
    print()
    
    # 分别转换收入和客户数据
    revenue_long = pd.melt(business_data,
                          id_vars=['year'],
                          value_vars=['revenue_online', 'revenue_offline'],
                          var_name='revenue_type',
                          value_name='revenue_amount')
    
    customers_long = pd.melt(business_data,
                            id_vars=['year'],
                            value_vars=['customers_new', 'customers_returning'],
                            var_name='customer_type',
                            value_name='customer_count')
    
    print("收入数据长格式:")
    print(revenue_long)
    print("\n客户数据长格式:")
    print(customers_long)
    print()
    
    return wide_df, melted_basic, grades_melted, sales_melted, multi_melted

def melt_usage_tips():
    """
    提供melt函数的使用技巧和最佳实践
    """
    print("7. melt() 函数使用技巧总结")
    print("-" * 40)
    print("✅ 选择合适的id_vars：保留作为标识符的列")
    print("✅ 使用value_vars精确控制：只转换需要的列")
    print("✅ 自定义列名：使用var_name和value_name提高可读性")
    print("✅ 处理缺失值：melt会保留原始数据中的NaN")
    print("✅ 多层索引：使用col_level参数指定要融化的级别")
    print("✅ 性能考虑：大数据集可分批处理")
    print("✅ 数据验证：转换后检查数据完整性和一致性")

# 运行演示
if __name__ == "__main__":
    # 执行演示函数
    original, basic_result, grades_result, sales_result, multi_result = demonstrate_melt_function()
    melt_usage_tips()
    
    print("\n" + "="*60)
    print("melt() 函数核心参数总结")
    print("="*60)
    print("📋 id_vars     : 保持不变的标识列（字符串或列表）")
    print("📋 value_vars  : 指定要转换的列（可选，默认除id_vars外所有列）")
    print("📋 var_name    : 新变量列的列名（默认'variable'）")
    print("📋 value_name  : 新值列的列名（默认'value'）")
    print("📋 col_level   : 多层列索引时指定要使用的级别")
    print("📋 ignore_index: 是否忽略原始索引（默认为True）")